package cloud.health.framework.computing.core;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Objects;

@Slf4j
public abstract class AbstractNettyServer {

    private static final int SO_BACKLOG = 1024;

    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private ServerBootstrap bootstrap;
    private ChannelFuture future;

    /**
     * 运行
     */
    public boolean run() {
        // 创建两个线程组 boosGroup、workerGroup
        this.bossGroup = new NioEventLoopGroup();
        this.workerGroup = new NioEventLoopGroup();
        // 创建服务端的启动对象，设置参数
        this.bootstrap = new ServerBootstrap();
        // 设置两个线程组boosGroup和workerGroup
        bootstrap.group(this.bossGroup, this.workerGroup)
                // 设置服务端通道实现类型
                .channel(NioServerSocketChannel.class)
                // 设置线程队列得到连接个数
                .option(ChannelOption.SO_BACKLOG, SO_BACKLOG)
                //.childOption(ChannelOption.SO_REUSEADDR, true) //快速复用端口
                // 开启了Nagle算法
                .childOption(ChannelOption.TCP_NODELAY, true)
                // 设置保持活动连接状态
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                // 给workerGroup的EventLoop对应的管道设置处理器
                .childHandler(channelInitializer());
        try {
            future = this.bootstrap.bind(this.port()).sync();
            log.info("server is running, port = {} future = {}", port(), future);
            // future.channel().closeFuture().sync();
            return true;
        } catch (InterruptedException e) {
            log.error("server runs error, port = {} --> \n", port(), e);
        }
        return false;
    }

    /**
     * 释放
     */
    @Override
    protected void finalize() throws Throwable {
        this.stop();
        super.finalize();
    }

    /**
     * 停止
     */
    public void stop() {
        if (Objects.nonNull(future)) {
            future.channel().close();
        }
        if (Objects.nonNull(this.bootstrap)) {
            this.bossGroup.shutdownGracefully();
        }
        if (Objects.nonNull(this.workerGroup)) {
            this.workerGroup.shutdownGracefully();
        }
        log.info("server is stop, port = {} future = {}", port(), future);
    }

    /**
     * 管道事务
     */
    public ChannelFuture getFuture() {
        return future;
    }

    /**
     * 绑定端口
     */
    protected abstract int port();

    /**
     * 管道处理器
     */
    protected abstract ChannelInitializer<SocketChannel> channelInitializer();
}
